<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>highpre智能AI剪辑</title>
    <link rel="icon" href="static/favicon.svg" type="image/svg+xml">

    <style>
        @font-face {
            font-family: 'MiSans', 'Microsoft YaHei', 'Segoe UI', sans-serif;
            src: url('/static/fonts/MiSans.ttf') format('truetype');
            font-weight: normal;
            font-style: normal;
            font-display: swap;
        }

        body {
            margin: 0;
            padding: 0;
            background-color: #000000; 
            color: white;
            font-family: 'MiSans', 'Segoe UI', sans-serif;
            height: 100vh;
            overflow: hidden;
            position: relative;
        }

        body::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: 
                linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)),
                repeating-linear-gradient(
                    0deg,
                    transparent,
                    transparent 2px,
                    rgba(0, 255, 255, 0.05) 2px,
                    rgba(0, 255, 255, 0.05) 4px
                ),
                repeating-linear-gradient(
                    90deg,
                    transparent,
                    transparent 2px,
                    rgba(255, 0, 255, 0.05) 2px,
                    rgba(255, 0, 255, 0.05) 4px
                );
            z-index: 0;
            pointer-events: none;
            animation: bg-animation 10s linear infinite;
        }

        @keyframes bg-animation {
            0% { background-position: 0 0; }
            100% { background-position: 100% 100%; }
        }

        @keyframes screen-flicker {
            0% { opacity: 0; }
            5% { opacity: 0.2; }
            10% { opacity: 0.1; }
            15% { opacity: 0.3; }
            20% { opacity: 0.2; }
            25% { opacity: 0.4; }
            30% { opacity: 0.3; }
            35% { opacity: 0.5; }
            40% { opacity: 0.4; }
            45% { opacity: 0.6; }
            50% { opacity: 0.5; }
            55% { opacity: 0.7; }
            60% { opacity: 0.6; }
            65% { opacity: 0.8; }
            70% { opacity: 0.7; }
            75% { opacity: 0.9; }
            80% { opacity: 0.8; }
            85% { opacity: 1; }
            90% { opacity: 0.9; }
            95% { opacity: 1; }
            100% { opacity: 1; }
        }

        .intro, .main-content {
            position: relative;
            z-index: 1;
        }

        .intro {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            opacity: 0;
            transition: opacity 1s ease;
            color: #39dcbb;
            text-shadow: 
                0 0 1px #00ffff,
                0 0 1px #00ffff,
                0 0 1px #00ffff;
            animation: screen-flicker 1.5s ease-out;
        }

        .line1, .line2 {
            display: block;
            opacity: 0;
            transition: opacity 0.6s ease;
        }

        .line1 {
            font-size: 48px;
            animation: fadeIn 0.8s ease-out forwards;
            animation-delay: 0.5s;
        }

        .line2 {
            font-size: 28px;
            animation: fadeIn 0.6s ease forwards;
            animation-delay: 1.2s;
        }

        .main-content {
            display: none;
            opacity: 0;
            transition: opacity 0.5s ease;
            height: 99vh;
            width: 176vh; 
            margin: 0 auto; 
            overflow: hidden;
            padding: 20px 0;
            margin-top: 1vh;
            box-sizing: border-box;
        }

        .content-wrapper {
            display: flex;
            height: 100%;
            gap: 20px;
            box-sizing: border-box;
        }

        .left-sidebar {
            flex: 1;
            min-width: 250px;
            max-width: 300px;
            display: flex;
            flex-direction: column;
            padding: 0 10px;
            overflow-y: auto;
            margin-top: 6vh;
        }

        .right-main-content {
            flex: 2;
            min-width: 300px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 0 20px;
            overflow-y: auto;
            overflow-x: hidden; 
        }

        .right-panel {
            flex: 1;
            min-width: 250px;
            max-width: 300px;
            margin-top: 6vh;
            display: flex;
            flex-direction: column;
            padding: 0 20px;
            overflow-y: auto;
        }

        @media (max-width: 1200px) {
            .content-wrapper {
                gap: 15px;
            }
            
            .left-sidebar, .right-panel {
                min-width: 200px;
            }
            
            .right-main-content {
                min-width: 250px;
            }
        }

        @media (max-width: 992px) {
            .main-content {
                width: 95vw;
            }
            
            .content-wrapper {
                gap: 10px;
            }
        }

        @media (max-width: 768px) {
            .content-wrapper {
                flex-direction: column;
                gap: 15px;
            }
            
            .left-sidebar, .right-panel {
                max-width: none;
                min-width: unset;
            }
            
            .right-main-content {
                min-width: unset;
            }
        }

        .video-preview {
            width: 100%;
            max-width: 1000px;
            aspect-ratio: 16 / 9;
            background-color: #111;
            border-radius: 10px;
            overflow: hidden;
            margin-bottom: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 1px solid #00ffff;
        }

        .video-preview video {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }

        .upload-analyze-container {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 40px;
            margin: 30px 0;
        }

        .upload-btn-wrapper,
        .analyze-btn-wrapper {
            position: relative;
            width: 10vw;
            height: 100%;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .upload-btn-wrapper img,
        .analyze-btn-wrapper img {
            width: 100%;
            height: 100%;
            object-fit: contain;
            transition: all 0.3s ease;
        }

        .upload-btn-wrapper input[type="file"] {
            font-size: 100px;
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0;
            cursor: pointer;
        }

        #cutVideoContainer {
            display: none;
        }

        @keyframes fadeIn {
            0% { opacity: 0; }
            100% { opacity: 1; }
        }
        
        .progress-container {
            width: 100%;
            max-width: 600px;
            height: 20px;
            background-color: #333;
            border-radius: 10px;
            margin: 10px 0;
            display: none;
            border: 1px solid #00ffff;
        }
        
        .progress-bar {
            height: 100%;
            background: linear-gradient(90deg, #00ffff, #9900ff);
            border-radius: 10px;
            width: 0%;
            transition: width 0.3s ease;
            box-shadow: 0 0 10px #00ffff;
        }
        
        .disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        
        #fileName {
            color: #39dcbb;
            margin: 10px 0;
        }
        
        .error-message {
            color: #ff6b6b;
            background-color: rgba(255, 0, 0, 0.1);
            border: 1px solid #ff6b6b;
            border-radius: 5px;
            padding: 10px;
            margin: 10px 0;
            display: none;
            text-align: left;
            font-family: monospace;
            font-size: 12px;
            max-width: 100%;
            overflow: auto;
        }
        
        .processing-text {
            color: #39dcbb;
            font-size: 18px;
            margin: 10px 0;
            display: none;
        }
        
        .ffmpeg-params-panel {
            background-color: rgba(0, 0, 0, 0.7);
            border-radius: 10px;
            padding: 20px;
            margin: 10px 0;
            border: 1px solid #00ffff;
            width: 100%;
            box-sizing: border-box;
        }

        .ffmpeg-params-panel > * {
            margin: 1vh 0;
        }
        
        .model-panel {
            background-color: rgba(0, 0, 0, 0.7);
            border-radius: 10px;
            padding: 20px;
            margin: 10px 0;
            border: 1px solid #00ffff;
            width: 100%;
            box-sizing: border-box;
        }
        .model-panel > * {
            margin: 0.6vh 0;
        }
        
        .panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            color: #39dcbb;
        }
        
        .panel-title {
            font-size: 20px;
            font-weight: bold;
        }
        
        .toggle-params {
            background: linear-gradient(45deg, #00ffff, #9900ff);
            color: #000;
            border: none;
            padding: 8px 15px;
            border-radius: 20px;
            cursor: pointer;
            font-family: 'MiSans', sans-serif;
            font-weight: bold;
            box-shadow: 0 0 10px #00ffff;
        }
        
        .param-row {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 10px;
        }
        
        .param-row .param-group {
            flex: 1;
            margin-bottom: 0;
        }
        
        .param-label {
            display: block;
            margin-bottom: 5px;
            color: white;
        }
        
        .param-input {
            width: 100%;
            padding: 8px;
            border-radius: 5px;
            border: 1px solid #00ffff;
            background-color: #333;
            color: white;
            box-sizing: border-box;
        }
        
        .param-slider {
            width: 100%;
            margin-top: 5px;
            accent-color: #00ffff;
        }
        
        .param-row {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
        }
        
        .param-row .param-group {
            flex: 1;
            margin-bottom: 0;
        }
        
        .advanced-toggle {
            color: #39dcbb;
            cursor: pointer;
            text-align: center;
            margin: 10px 0;
            font-size: 14px;
        }
        
        .advanced-params {
            display: none;
        }
        
        .reset-btn {
            background: linear-gradient(45deg, #ff00ff, #00ffff);
            color: white;
            border: none;
            padding: 10px 15px;
            border-radius: 5px;
            cursor: pointer;
            font-family: 'MiSans', sans-serif;
            font-weight: bold;
            margin-top: 10px;
            width: 100%;
            box-shadow: 0 0 10px #ff00ff;
        }
        
        .reset-btn:hover {
            background: linear-gradient(45deg, #ff00ff, #00ffff);
            box-shadow: 0 0 15px #ff00ff;
        }
        
        .text-display {
            width: 100%;
            height: 150px;
            background-color: rgba(0, 0, 0, 0.7);
            border: 1px solid #00ffff;
            border-radius: 10px;
            padding: 10px;
            margin: 10px 0;
            color: white;
            font-family: 'MiSans', monospace;
            font-size: 14px;
            resize: vertical;
            box-sizing: border-box;
        }
        
        .model-panel .text-display {
            height: 100px;
        }
        
        .left-sidebar::-webkit-scrollbar,
        .right-main-content::-webkit-scrollbar,
        .right-panel::-webkit-scrollbar {
            width: 8px;
            background: rgba(0, 0, 0, 0.3);
        }
        
        .left-sidebar::-webkit-scrollbar-thumb,
        .right-main-content::-webkit-scrollbar-thumb,
        .right-panel::-webkit-scrollbar-thumb {
            background: linear-gradient(#00ffff, #9900ff);
            border-radius: 4px;
        }
        
        .left-sidebar,
        .right-main-content,
        .right-panel {
            scrollbar-width: thin;
            scrollbar-color: #00ffff rgba(0, 0, 0, 0.3);
        }
        
        .card {
            transition: all 0.3s ease;
            transform-origin: center;
            border: 1px solid transparent;
        }

        .card:hover {
            transform: scale(1.02);
            box-shadow: 
                0 0 10px #9900ff,
                0 0 20px #9900ff,
                inset 0 0 10px #00ffff;
            border: 1px solid #00ffff;
        }

        .upload-btn-wrapper:hover img,
        .analyze-btn-wrapper:hover img {
            width: 100%;
        }

        .ffmpeg-params-panel.custom-panel {
            width: 100%;
        }
        
        .model-panel.custom-panel {
            width: 100%;
        }
        
        .right-main-content.custom-content {
            width: 100%;
        }

        .upload-analyze-container .card:hover,
        .upload-btn-wrapper:hover,
        .analyze-btn-wrapper:hover,
        .cut-btn-wrapper:hover {
            transform: none;
            box-shadow: none;
            border: none;
        }

        .main-title {
            color: #39dcbb;
            text-align: center;
            margin: 10px 0 20px 0;
            font-weight: bold;
            font-size: clamp(24px, 4vw, 48px);
        }
    </style>
</head>
<body>
    <div class="intro" id="intro">
        <span class="line1" id="line1">欢迎使用</span><br>
        <span class="line2" id="line2">highpre智能AI剪辑系统</span>
    </div>

    <div class="main-content" id="mainContent">
        <div class="content-wrapper">
            <div class="left-sidebar">
                <div class="model-panel card custom-panel">
                    <div class="panel-header">
                        <div class="panel-title">模型设置</div>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">模型来源</label>
                        <select class="param-input" id="modelSource">
                            <option value="local" selected>Ollama</option>
                            <option value="xfyun">讯飞星火</option>
                            <option value="tencent">腾讯云</option>
                        </select>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">模型选择</label>
                        <select class="param-input" id="modelSelection">
                            <!-- Ollama 模型 -->
                            <option value="qwen2.5vl:3b" data-source="local" selected>qwen2.5vl:3b</option>
                            <option value="llama3" data-source="local">Llama 3</option>
                            <option value="qwen3" data-source="local">qwen3</option>
                            
                            <!-- 讯飞星火模型 -->
                            <option value="4.0Ultra" data-source="xfyun" selected>4.0 Ultra</option>
                            <option value="3.5" data-source="xfyun">Spark 3.5</option>
                            <option value="3.0" data-source="xfyun">Spark 3.1</option>
                            
                            <!-- 腾讯云模型 -->
                            <option value="hunyuan-lite" data-source="tencent">Hunyuan Lite</option>
                            <option value="hunyuan-standard" data-source="tencent">Hunyuan Standard</option>
                            <option value="hunyuan-pro" data-source="tencent">Hunyuan Pro</option>

                            <!-- Kimi 模型 -->
                            <option value="kimi-k2" data-source="kimi">Kimi K2</option>
                            
                            <!-- ModelScope 模型 -->
                            <option value="MusePublic/FLUX.1-Kontext-Dev" data-source="modelscope">FLUX.1-Kontext-Dev</option>
                        </select>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">剪辑需求描述</label>
                        <textarea class="param-input text-display" id="editingRequirements" placeholder="描述您的剪辑需求，例如：提取产品介绍片段、剪出精彩瞬间等..."></textarea>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">期望片段长度 (秒)</label>
                        <input type="number" class="param-input" id="expectedClipLength" min="1" value="3" step="1">
                    </div>
                    
                    <div class="param-row">
                        <div class="param-group">
                            <label class="param-label">模型温度 (0-2)</label>
                            <input type="number" class="param-input" id="modelTemperature" min="0" max="2" value="0.7" step="0.1">
                            <input type="range" class="param-slider" id="temperatureSlider" min="0" max="20" value="7" step="1">
                        </div>
                        
                        <div class="param-group">
                            <label class="param-label">随机种子</label>
                            <input type="number" class="param-input" id="randomSeed" min="0" value="42">
                        </div>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">Top-P (0-1)</label>
                        <input type="number" class="param-input" id="topP" min="0" max="1" value="0.9" step="0.01">
                        <input type="range" class="param-slider" id="topPSlider" min="0" max="100" value="90" step="1">
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">最大输出长度</label>
                        <input type="number" class="param-input" id="maxTokens" min="1" max="4096" value="1024">
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">关键词权重</label>
                        <input type="text" class="param-input" id="keywordWeights" placeholder="关键词1:权重1,关键词2:权重2">
                    </div>
                </div>
            </div>
            
            <div class="right-main-content custom-content">
                <div class="main-title">highpre帮您高效处理视频素材</div>
                
                <div class="video-preview card" id="videoPreview"></div>
                
                <div class="processing-text" id="processingText">后台处理中，请稍候...</div>
                
                <div class="progress-container" id="progressContainer">
                    <div class="progress-bar" id="progressBar"></div>
                </div>
                
                <div class="error-message" id="errorMessage"></div>

                <div class="upload-analyze-container">
                    <div class="upload-btn-wrapper" id="uploadBtnWrapper">
                        <img src="static/images/upload-icon.png" alt="选择视频">
                        <input type="file" accept="video/*" id="videoInput">
                    </div>

                    <div class="analyze-btn-wrapper" id="analyzeBtnWrapper">
                        <img src="static/images/analyze-icon.png" alt="分析视频">
                    </div>
                    
                    <div class="analyze-btn-wrapper" id="cutBtnWrapper">
                        <img src="static/images/cut-icon.png" alt="剪辑视频">
                    </div>
                </div>

                <p id="fileName"></p>

                <div id="cutVideoContainer" class="video-preview card" style="margin-top: 30px;"></div>
            </div>
            
            <div class="right-panel">
                <div class="ffmpeg-params-panel card custom-panel" id="ffmpegParamsPanel">
                    <div class="panel-header">
                        <div class="panel-title">FFmpeg 参数设置</div>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">视频编码器 (-c:v)</label>
                        <select class="param-input" id="videoCodec">
                            <option value="libx264">libx264 (H.264)</option>
                            <option value="libx265">libx265 (H.265/HEVC)</option>
                            <option value="vp9">vp9 (VP9)</option>
                            <option value="h264_nvenc">h264_nvenc (NVIDIA GPU)</option>
                        </select>
                    </div>
                    
                    <div class="param-group">
                        <label class="param-label">音频编码器 (-c:a)</label>
                        <select class="param-input" id="audioCodec">
                            <option value="aac">aac</option>
                            <option value="mp3">mp3</option>
                            <option value="opus">opus</option>
                            <option value="vorbis">vorbis</option>
                        </select>
                    </div>
                    
                    <div class="param-row">
                        <div class="param-group">
                            <label class="param-label">质量 (CRF: 0-51)</label>
                            <input type="number" class="param-input" id="crfValue" min="0" max="51" value="23">
                            <input type="range" class="param-slider" id="crfSlider" min="0" max="51" value="23">
                        </div>
                        <div class="param-group">
                            <label class="param-label">起始时间 (秒)</label>
                            <input type="number" class="param-input" id="startTime" min="0" value="0" step="0.1">
                        </div>
                        
                        <div class="param-group">
                            <label class="param-label">结束时间 (秒)</label>
                            <input type="number" class="param-input" id="endTime" min="0" value="10" step="0.1">
                        </div>
                        <div class="param-group">
                            <label class="param-label">编码预设 (-preset)</label>
                            <select class="param-input" id="presetValue">
                                <option value="ultrafast">ultrafast</option>
                                <option value="superfast">superfast</option>
                                <option value="veryfast">veryfast</option>
                                <option value="faster">faster</option>
                                <option value="fast">fast</option>
                                <option value="medium" selected>medium</option>
                                <option value="slow">slow</option>
                                <option value="slower">slower</option>
                                <option value="veryslow">veryslow</option>
                            </select>
                        </div>
                    </div>
                    
                    <div class="advanced-toggle" id="advancedToggle">显示高级参数 ▼</div>
                    
                    <div class="advanced-params" id="advancedParams">
                        <div class="param-group">
                            <label class="param-label">像素格式 (-pix_fmt)</label>
                            <select class="param-input" id="pixFmt">
                                <option value="yuv420p" selected>yuv420p</option>
                                <option value="yuv422p">yuv422p</option>
                                <option value="yuv444p">yuv444p</option>
                                <option value="yuvj420p">yuvj420p</option>
                            </select>
                        </div>
                        
                        <div class="param-group">
                            <label class="param-label">Movflags (-movflags)</label>
                            <input type="text" class="param-input" id="movFlags" value="+faststart">
                        </div>
                        
                        <div class="param-group">
                            <label class="param-label">其他参数</label>
                            <input type="text" class="param-input" id="otherParams" placeholder="例如: -b:v 1000k -maxrate 1500k">
                        </div>
                    </div>
                    
                    <button class="reset-btn" id="resetParamsBtn">重置为默认值</button>
                </div>
                <textarea class="text-display card" id="textDisplay" placeholder="处理信息将显示在这里..."></textarea>
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const intro = document.querySelector('.intro');
            const line1 = document.getElementById('line1');
            const line2 = document.getElementById('line2');
            const mainContent = document.getElementById('mainContent');
            const uploadBtnWrapper = document.getElementById('uploadBtnWrapper');
            const analyzeBtnWrapper = document.getElementById('analyzeBtnWrapper');
            const cutBtnWrapper = document.getElementById('cutBtnWrapper');
            const videoInput = document.getElementById('videoInput');
            const fileName = document.getElementById('fileName');
            const videoPreview = document.getElementById('videoPreview');
            const cutVideoContainer = document.getElementById('cutVideoContainer');
            const progressContainer = document.getElementById('progressContainer');
            const progressBar = document.getElementById('progressBar');
            const errorMessage = document.getElementById('errorMessage');
            const processingText = document.getElementById('processingText');
            const textDisplay = document.getElementById('textDisplay');

            const advancedToggle = document.getElementById('advancedToggle');
            const advancedParams = document.getElementById('advancedParams');
            const resetParamsBtn = document.getElementById('resetParamsBtn');
            
            const videoCodec = document.getElementById('videoCodec');
            const audioCodec = document.getElementById('audioCodec');
            const crfValue = document.getElementById('crfValue');
            const crfSlider = document.getElementById('crfSlider');
            const presetValue = document.getElementById('presetValue');
            const pixFmt = document.getElementById('pixFmt');
            const movFlags = document.getElementById('movFlags');
            const otherParams = document.getElementById('otherParams');
            
            const startTime = document.getElementById('startTime');
            const endTime = document.getElementById('endTime');
            
            const modelSource = document.getElementById('modelSource');
            const modelSelection = document.getElementById('modelSelection');
            const editingRequirements = document.getElementById('editingRequirements');
            const expectedClipLength = document.getElementById('expectedClipLength');
            const modelTemperature = document.getElementById('modelTemperature');
            const temperatureSlider = document.getElementById('temperatureSlider');
            const randomSeed = document.getElementById('randomSeed');
            const topP = document.getElementById('topP');
            const topPSlider = document.getElementById('topPSlider');
            const maxTokens = document.getElementById('maxTokens');
            const keywordWeights = document.getElementById('keywordWeights');

            let currentVideo = null;
            let selectedFilePath = null;
            
            let ffmpegParams = {
                videoCodec: 'libx264',
                audioCodec: 'aac',
                crf: 23,
                preset: 'fast',
                pixFmt: 'yuv420p',
                movFlags: '+faststart',
                otherParams: '',
                startTime: 0,
                endTime: 10
            };
            
            let modelParams = {
                source: 'local',
                model: 'qwen2.5vl:3b',
                requirements: '',
                clipLength: 30,
                temperature: 0.7,
                seed: 42,
                topP: 0.9,
                maxTokens: 1024,
                keywords: ''
            };

            analyzeBtnWrapper.classList.add('disabled');
            cutBtnWrapper.classList.add('disabled');

            setTimeout(() => {
                intro.style.opacity = 1;
            }, 100);

            setTimeout(() => {
                intro.style.opacity = 0;
                intro.style.pointerEvents = 'none';

                mainContent.style.display = 'block';
                mainContent.style.opacity = '1';
            }, 4000);

            videoInput.addEventListener('change', function () {
                const file = videoInput.files[0];
                if (!file) return;

                fileName.textContent = '已选择视频: ' + file.name;

                if (currentVideo) {
                    currentVideo.pause();
                    currentVideo.srcObject = null;
                    currentVideo = null;
                }

                const videoURL = URL.createObjectURL(file);
                const videoElement = document.createElement('video');
                videoElement.src = videoURL;
                videoElement.controls = true;
                videoElement.autoplay = true;
                videoElement.loop = false;
                videoElement.muted = true;

                videoPreview.innerHTML = '';
                videoPreview.appendChild(videoElement);
                currentVideo = videoElement;

                analyzeBtnWrapper.classList.remove('disabled');
                cutBtnWrapper.classList.remove('disabled');
                
                selectedFilePath = file.name;
                
                errorMessage.style.display = 'none';
                
                videoElement.addEventListener('loadedmetadata', function() {
                    endTime.value = Math.floor(videoElement.duration * 10) / 10;
                    ffmpegParams.endTime = endTime.value;
                });
            });

            analyzeBtnWrapper.addEventListener('click', function () {
                if (analyzeBtnWrapper.classList.contains('disabled')) {
                    return;
                }

                if (!currentVideo) {
                    alert('请先选择视频');
                    return;
                }

                switch(modelSource.value) {
                    case 'local':
                        callOllamaAPI();
                        break;
                    case 'xfyun':
                        callXfyunAPI();
                        break;
                    case 'tencent':
                        callTencentAPI();
                        break;
                    default:
                        callOllamaAPI();
                }
            });
            
            cutBtnWrapper.addEventListener('click', function () {
                if (cutBtnWrapper.classList.contains('disabled')) {
                    return;
                }

                if (!currentVideo) {
                    alert('请先选择视频');
                    return;
                }

                const start = parseFloat(startTime.value);
                const end = parseFloat(endTime.value);
                
                if (isNaN(start) || isNaN(end) || start >= end) {
                    alert('请设置有效的起始时间和结束时间');
                    return;
                }

                cutVideoOnServer(start, end, selectedFilePath);
            });

            advancedToggle.addEventListener('click', function() {
                if (advancedParams.style.display === 'none') {
                    advancedParams.style.display = 'block';
                    advancedToggle.textContent = '隐藏高级参数 ▲';
                } else {
                    advancedParams.style.display = 'none';
                    advancedToggle.textContent = '显示高级参数 ▼';
                }
            });
            
            crfValue.addEventListener('input', function() {
                crfSlider.value = crfValue.value;
                ffmpegParams.crf = parseInt(crfValue.value);
            });
            
            crfSlider.addEventListener('input', function() {
                crfValue.value = crfSlider.value;
                ffmpegParams.crf = parseInt(crfSlider.value);
            });
            
            startTime.addEventListener('input', function() {
                ffmpegParams.startTime = parseFloat(startTime.value) || 0;
            });
            
            endTime.addEventListener('input', function() {
                ffmpegParams.endTime = parseFloat(endTime.value) || 10;
            });
            
            videoCodec.addEventListener('change', function() {
                ffmpegParams.videoCodec = videoCodec.value;
            });
            
            audioCodec.addEventListener('change', function() {
                ffmpegParams.audioCodec = audioCodec.value;
            });
            
            presetValue.addEventListener('change', function() {
                ffmpegParams.preset = presetValue.value;
            });
            
            pixFmt.addEventListener('change', function() {
                ffmpegParams.pixFmt = pixFmt.value;
            });
            
            movFlags.addEventListener('input', function() {
                ffmpegParams.movFlags = movFlags.value;
            });
            
            otherParams.addEventListener('input', function() {
                ffmpegParams.otherParams = otherParams.value;
            });
            
            modelSource.addEventListener('change', function() {
                modelParams.source = modelSource.value;
                
                const options = modelSelection.querySelectorAll('option');
                options.forEach(option => {
                    if (option.dataset.source === modelSource.value) {
                        option.style.display = '';
                    } else {
                        option.style.display = 'none';
                    }
                });
                
                const visibleOptions = Array.from(options).filter(option => 
                    option.dataset.source === modelSource.value
                );
                
                if (visibleOptions.length > 0) {
                    modelSelection.value = visibleOptions[0].value;
                    modelParams.model = visibleOptions[0].value;
                }
            });

            modelSelection.addEventListener('change', function() {
                modelParams.model = modelSelection.value;
            });

            editingRequirements.addEventListener('input', function() {
                modelParams.requirements = editingRequirements.value;
            });

            expectedClipLength.addEventListener('input', function() {
                modelParams.clipLength = parseInt(expectedClipLength.value) || 30;
            });

            modelTemperature.addEventListener('input', function() {
                temperatureSlider.value = parseFloat(modelTemperature.value) * 10;
                modelParams.temperature = parseFloat(modelTemperature.value);
            });

            temperatureSlider.addEventListener('input', function() {
                modelTemperature.value = (temperatureSlider.value / 10).toFixed(1);
                modelParams.temperature = parseFloat(modelTemperature.value);
            });

            randomSeed.addEventListener('input', function() {
                modelParams.seed = parseInt(randomSeed.value) || 42;
            });

            topP.addEventListener('input', function() {
                topPSlider.value = parseFloat(topP.value) * 100;
                modelParams.topP = parseFloat(topP.value);
            });

            topPSlider.addEventListener('input', function() {
                topP.value = (topPSlider.value / 100).toFixed(2);
                modelParams.topP = parseFloat(topP.value);
            });

            maxTokens.addEventListener('input', function() {
                modelParams.maxTokens = parseInt(maxTokens.value) || 1024;
            });

            keywordWeights.addEventListener('input', function() {
                modelParams.keywords = keywordWeights.value;
            });
            
            resetParamsBtn.addEventListener('click', function() {
                videoCodec.value = 'libx264';
                audioCodec.value = 'aac';
                crfValue.value = 23;
                crfSlider.value = 23;
                presetValue.value = 'fast';
                pixFmt.value = 'yuv420p';
                movFlags.value = '+faststart';
                otherParams.value = '';
                startTime.value = 0;
                endTime.value = 10;
                
                ffmpegParams = {
                    videoCodec: 'libx264',
                    audioCodec: 'aac',
                    crf: 23,
                    preset: 'fast',
                    pixFmt: 'yuv420p',
                    movFlags: '+faststart',
                    otherParams: '',
                    startTime: 0,
                    endTime: 10
                };
                
                textDisplay.value += "参数已重置为默认值\n";
            });

            function callOllamaAPI() {
                processingText.style.display = 'block';
                textDisplay.value = "正在请求AI分析...\n";
                
                analyzeBtnWrapper.classList.add('disabled');
                
                const requestData = {
                    prompt: editingRequirements.value,
                    model: modelSelection.value,
                    temperature: parseFloat(modelTemperature.value),
                    seed: parseInt(randomSeed.value),
                    maxTokens: parseInt(maxTokens.value)
                };
                
                fetch('/ollama', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                })
                .then(response => response.json())
                .then(data => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    processingText.style.display = 'none';
                    
                    if (data.code === 0) {
                        if (data.data && data.data.response) {
                            textDisplay.value += "AI 分析结果:\n" + data.data.response + "\n";
                        }
                        
                        errorMessage.style.display = 'none';
                    } else {
                        errorMessage.textContent = `AI 分析失败: ${data.message}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "AI 分析失败: " + data.message + "\n";
                        alert('AI 分析失败: ' + data.message);
                    }
                })
                .catch(error => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    errorMessage.textContent = `网络错误: ${error.message}`;
                    errorMessage.style.display = 'block';
                    textDisplay.value += "网络错误: " + error.message + "\n";
                    textDisplay.value += "错误详情: " + JSON.stringify(error, null, 2) + "\n";
                    alert('调用 AI 分析接口失败: ' + error.message);
                });
            }
            
            function callXfyunAPI() {
                processingText.style.display = 'block';
                textDisplay.value = "正在请求AI分析...\n";
                
                analyzeBtnWrapper.classList.add('disabled');
                
                const requestData = {
                    prompt: editingRequirements.value ,
                    model: modelSelection.value,
                    temperature: parseFloat(modelTemperature.value),
                    maxTokens: parseInt(maxTokens.value)
                };
                
                fetch('/xfyun', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                })
                .then(response => response.json())
                .then(data => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    processingText.style.display = 'none';
                    
                    if (data.code === 0) {
                        if (data.data && data.data.response) {
                            textDisplay.value += "AI 分析结果:\n" + data.data.response + "\n";
                        }
                        
                        errorMessage.style.display = 'none';
                    } else {
                        errorMessage.textContent = `AI 分析失败: ${data.message}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "AI 分析失败: " + data.message + "\n";
                        alert('AI 分析失败: ' + data.message);
                    }
                })
                .catch(error => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    errorMessage.textContent = `网络错误: ${error.message}`;
                    errorMessage.style.display = 'block';
                    textDisplay.value += "网络错误: " + error.message + "\n";
                    textDisplay.value += "错误详情: " + JSON.stringify(error, null, 2) + "\n";
                    alert('调用 AI 分析接口失败: ' + error.message);
                });
            }
            
            function callTencentAPI() {
                processingText.style.display = 'block';
                textDisplay.value = "正在请求AI分析...\n";
                
                analyzeBtnWrapper.classList.add('disabled');
                
                const requestData = {
                    prompt: editingRequirements.value,
                    model: modelSelection.value,
                    temperature: parseFloat(modelTemperature.value),
                    maxTokens: parseInt(maxTokens.value)
                };
                
                fetch('/tencent', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                })
                .then(response => response.json())
                .then(data => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    processingText.style.display = 'none';
                    
                    if (data.code === 0) {
                        if (data.data && data.data.response) {
                            textDisplay.value += "AI 分析结果:\n" + data.data.response + "\n";
                        }
                        
                        errorMessage.style.display = 'none';
                    } else {
                        errorMessage.textContent = `AI 分析失败: ${data.message}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "AI 分析失败: " + data.message + "\n";
                        alert('AI 分析失败: ' + data.message);
                    }
                })
                .catch(error => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    errorMessage.textContent = `网络错误: ${error.message}`;
                    errorMessage.style.display = 'block';
                    textDisplay.value += "网络错误: " + error.message + "\n";
                    textDisplay.value += "错误详情: " + JSON.stringify(error, null, 2) + "\n";
                    alert('调用 AI 分析接口失败: ' + error.message);
                });
            }
            

            function callKimiAPI() {
                processingText.style.display = 'block';
                textDisplay.value = "正在请求Kimi AI分析...\n";
                
                analyzeBtnWrapper.classList.add('disabled');
                
                const requestData = {
                    prompt: editingRequirements.value,
                    model: modelSelection.value,
                    temperature: parseFloat(modelTemperature.value),
                    maxTokens: parseInt(maxTokens.value)
                };
                
                fetch('/kimi', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                })
                .then(response => response.json())
                .then(data => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    processingText.style.display = 'none';
                    
                    if (data.code === 0) {
                        if (data.data && data.data.response) {
                            textDisplay.value += "Kimi AI 分析结果:\n" + data.data.response + "\n";
                        }
                        
                        errorMessage.style.display = 'none';
                    } else {
                        errorMessage.textContent = `Kimi AI 分析失败: ${data.message}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "Kimi AI 分析失败: " + data.message + "\n";
                        alert('Kimi AI 分析失败: ' + data.message);
                    }
                })
                .catch(error => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    errorMessage.textContent = `网络错误: ${error.message}`;
                    errorMessage.style.display = 'block';
                    textDisplay.value += "网络错误: " + error.message + "\n";
                    textDisplay.value += "错误详情: " + JSON.stringify(error, null, 2) + "\n";
                    alert('调用 Kimi AI 分析接口失败: ' + error.message);
                });
            }

            function callModelScopeAPI() {
                processingText.style.display = 'block';
                textDisplay.value = "正在请求ModelScope AI分析...\n";
                
                analyzeBtnWrapper.classList.add('disabled');
                
                const requestData = {
                    prompt: editingRequirements.value,
                    model: modelSelection.value,
                    temperature: parseFloat(modelTemperature.value),
                    maxTokens: parseInt(maxTokens.value)
                };
                
                fetch('/modelscope', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                })
                .then(response => response.json())
                .then(data => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    processingText.style.display = 'none';
                    
                    if (data.code === 0) {
                        if (data.data && data.data.response) {
                            textDisplay.value += "ModelScope AI 分析结果:\n" + data.data.response + "\n";
                        }
                        
                        errorMessage.style.display = 'none';
                    } else {
                        errorMessage.textContent = `ModelScope AI 分析失败: ${data.message}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "ModelScope AI 分析失败: " + data.message + "\n";
                        alert('ModelScope AI 分析失败: ' + data.message);
                    }
                })
                .catch(error => {
                    analyzeBtnWrapper.classList.remove('disabled');
                    
                    errorMessage.textContent = `网络错误: ${error.message}`;
                    errorMessage.style.display = 'block';
                    textDisplay.value += "网络错误: " + error.message + "\n";
                    textDisplay.value += "错误详情: " + JSON.stringify(error, null, 2) + "\n";
                    alert('调用 ModelScope AI 分析接口失败: ' + error.message);
                });
            }

            analyzeBtnWrapper.addEventListener('click', function () {
                if (analyzeBtnWrapper.classList.contains('disabled')) {
                    return;
                }

                if (!currentVideo) {
                    alert('请先选择视频');
                    return;
                }

                switch(modelSource.value) {
                    case 'local':
                        callOllamaAPI();
                        break;
                    case 'xfyun':
                        callXfyunAPI();
                        break;
                    case 'tencent':
                        callTencentAPI();
                        break;
                    case 'kimi':
                        callKimiAPI();
                        break;
                    case 'modelscope':
                        callModelScopeAPI();
                        break;
                    default:
                        callOllamaAPI();
                }
            });
            
            function cutVideoOnServer(start, end, filename) {
                progressContainer.style.display = 'block';
                processingText.style.display = 'block';
                progressBar.style.width = '0%';
                textDisplay.value = "开始处理视频...\n";
                
                cutBtnWrapper.classList.add('disabled');
                
                let progress = 0;
                const interval = setInterval(() => {
                    progress += Math.random() * 10;
                    if (progress >= 100) {
                        progress = 100;
                        clearInterval(interval);
                    }
                    progressBar.style.width = progress + '%';
                }, 200);

                fetch('/cut_video', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        start: start.toFixed(2),
                        end: end.toFixed(2),
                        path: '/videos/input',
                        name: filename,
                        ffmpegParams: ffmpegParams
                    })
                })
                .then(response => response.json())
                .then(data => {
                    clearInterval(interval);
                    progressBar.style.width = '100%';
                    
                    setTimeout(() => {
                        progressContainer.style.display = 'none';
                        processingText.style.display = 'none';
                    }, 500);
                    
                    cutBtnWrapper.classList.remove('disabled');
                    
                    if (data.code === 0) {
                        textDisplay.value += "视频剪辑成功!\n输出路径: " + data.data.output + "\n"+"点击跳转界面";
                        
                        errorMessage.style.display = 'none';
                        
                        window.location.href = 'http://127.0.0.1:5839/result';
                    } else {
                        errorMessage.textContent = `剪辑失败: ${data.message}\n${data.error || ''}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "剪辑失败: " + data.message + "\n";
                        alert('剪辑失败: ' + data.message);
                    }
                })
                .catch(error => {
                    clearInterval(interval);
                    
                    progressContainer.style.display = 'none';
                    processingText.style.display = 'none';
                    
                    cutBtnWrapper.classList.remove('disabled');
                    
                    errorMessage.textContent = `网络错误: ${error.message}`;
                    errorMessage.style.display = 'block';
                    textDisplay.value += "网络错误: " + error.message + "\n";
                    alert('调用剪辑接口失败: ' + error.message);
                });
            }

            function resetModelParams() {
                modelSource.value = 'local';
                modelSelection.value = 'qwen2.5vl:3b';
                editingRequirements.value = '';
                expectedClipLength.value = 30;
                modelTemperature.value = 0.7;
                temperatureSlider.value = 7;
                randomSeed.value = 42;
                topP.value = 0.9;
                topPSlider.value = 90;
                maxTokens.value = 1024;
                keywordWeights.value = '';
                
                modelParams = {
                    source: 'local',
                    model: 'qwen2.5vl:3b',
                    requirements: '',
                    clipLength: 30,
                    temperature: 0.7,
                    seed: 42,
                    topP: 0.9,
                    maxTokens: 1024,
                    keywords: ''
                };
                
                textDisplay.value += "模型参数已重置为默认值\n";
            }
        });

            function analyzeVideoContent() {
                if (!currentVideo) {
                    alert('请先选择视频');
                    return;
                }

                processingText.style.display = 'block';
                textDisplay.value = "正在分析视频内容...\n";
                
                analyzeBtnWrapper.classList.add('disabled');
                
                // 获取视频base64编码
                const file = videoInput.files[0];
                if (!file) {
                    alert('请先选择视频文件');
                    analyzeBtnWrapper.classList.remove('disabled');
                    return;
                }
                
                const reader = new FileReader();
                reader.onload = function(e) {
                    // 提取base64数据
                    const base64Data = e.target.result.split(',')[1]; // 去掉data:*/*;base64,前缀
                    
                    // 构建请求数据
                    const requestData = {
                        video_name: selectedFilePath,
                        requirements: editingRequirements.value,
                        model_source: modelSource.value,
                        model: modelSelection.value,
                        temperature: parseFloat(modelTemperature.value),
                        seed: parseInt(randomSeed.value),
                        maxTokens: parseInt(maxTokens.value),
                        topP: parseFloat(topP.value),
                        keywordWeights: keywordWeights.value,
                        expectedClipLength: parseInt(expectedClipLength.value) || 30
                    };
                    
                    // 发送请求到后端
                    fetch('/analyze_video_content', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(requestData)
                    })
                    .then(response => response.json())
                    .then(data => {
                        analyzeBtnWrapper.classList.remove('disabled');
                        processingText.style.display = 'none';
                        
                        if (data.code === 0) {
                            textDisplay.value += "视频内容分析结果:\n" + data.data.content_analysis + "\n\n";
                            textDisplay.value += "剪辑建议:\n" + data.data.editing_suggestion + "\n";
                            
                            // 自动填充FFmpeg参数
                            startTime.value = data.data.start_time;
                            endTime.value = data.data.end_time;
                            ffmpegParams.startTime = data.data.start_time;
                            ffmpegParams.endTime = data.data.end_time;
                            
                            textDisplay.value += `\n已自动设置剪辑时间段: ${data.data.start_time}秒 到 ${data.data.end_time}秒\n`;
                            
                            errorMessage.style.display = 'none';
                        } else {
                            errorMessage.textContent = `视频分析失败: ${data.message}`;
                            errorMessage.style.display = 'block';
                            textDisplay.value += "视频分析失败: " + data.message + "\n";
                            alert('视频分析失败: ' + data.message);
                        }
                    })
                    .catch(error => {
                        analyzeBtnWrapper.classList.remove('disabled');
                        processingText.style.display = 'none';
                        
                        errorMessage.textContent = `网络错误: ${error.message}`;
                        errorMessage.style.display = 'block';
                        textDisplay.value += "网络错误: " + error.message + "\n";
                        textDisplay.value += "错误详情: " + JSON.stringify(error, null, 2) + "\n";
                        alert('调用视频分析接口失败: ' + error.message);
                    });
                };
                
                reader.onerror = function() {
                    alert('读取视频文件失败');
                    analyzeBtnWrapper.classList.remove('disabled');
                };
                
                // 读取文件为base64
                reader.readAsDataURL(file);
            }

            // 修改analyzeBtnWrapper的点击事件处理函数
            analyzeBtnWrapper.addEventListener('click', function () {
                if (analyzeBtnWrapper.classList.contains('disabled')) {
                    return;
                }

                if (!currentVideo) {
                    alert('请先选择视频');
                    return;
                }
                analyzeVideoContent();
            });
    </script>

</body>
</html>